<script setup>
import { toRef,useAttrs,inject } from 'vue'
const emit = defineEmits(['sendMsg','update:firstName', 'update:lastName'])//声明需要抛出的事件
// const props = defineProps(['msg'])
// 或用对象形式声明
const props = defineProps({
  msg:String,
  firstName: String,
  lastName: String
})
//如果想在子组件中用其它变量接收props的值时需要使用toRef将props中的属性转为响应式。
let parentMsg = toRef(props, 'msg')//props中数据流是单项的，即子组件不可改变父组件传来的值
const sendMsg = () => {
  emit('sendMsg', '子组件数据')//(传递过去的函数名，穿传递过去的数据)
}

/**
 * 子组件使用$attrs可以获得父组件除了props传递的属性和特性绑定属性 (class和 style)之外的所有属性。
 *  子组件使用$listeners可以获得父组件(不含.native修饰器的)所有v-on事件监听器，在Vue3中已经不再使用；但是Vue3中的attrs不仅可以获得父组件传来的属性也可以获得父组件v-on事件监听器
 * */
 const attrs = useAttrs()
//获取父组件方法和事件
console.log(attrs) //Proxy {"msg1": "子组件msg1","msg2": "子组件msg2"}
const getParentFun = () => {
    //调用父组件方法
    attrs.onParentFun('我是子组件数据')//Vue3中使用attrs调用父组件方法时，方法前需要加上on；如parentFun->onParentFun
}

/**
 * provide：是一个对象，或者是一个返回对象的函数。里面包含要给子孙后代属性
 * inject：一个字符串数组，或者是一个对象。获取父组件或更高层次的组件provide的值，既在任何后代组件都可以通过inject获得
 * */
console.log('利用provide传输对象',inject('prodata').value);
const {son1demoData,changeson1demoData} = inject('son1demoData')
console.log('son',son1demoData.value);

//v-model举例

// defineEmits(['update:firstName', 'update:lastName'])
</script>
  <template>
  <div>子组件</div>
  <p>{{  parentMsg  }}</p>
  <button @click="sendMsg">点击向父组件发送消息</button>
  <button @click="emit('sendhang','串案')">行内方法传参</button>
  <button @click="getParentFun">点击调用父组件方法</button>

  <input :value="props.firstName" @input="$emit('update:firstName',$event.target.value)"/>
</template>
  